package com.learning.thread.juc.atomic;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ClassName: AtomicAndLock
 * Description:
 * Date: 2016/11/26 15:21 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class AtomicAndLock {


    void testSyncTask() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREAD);

        long startTime = System.currentTimeMillis();

        SyncTask syncTask = new SyncTask(startTime, this);
        for (int i = 0; i < TASK_COUNT; i++) {
            executorService.execute(syncTask);
        }

        Thread.sleep(10000L);
    }

    void testAtomicTask() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(MAX_THREAD);

        long startTime = System.currentTimeMillis();

        AtomicTask atomicTask = new AtomicTask(startTime);
        for (int i = 0; i < TASK_COUNT; i++) {
            executorService.execute(atomicTask);
        }

        Thread.sleep(10000L);
    }


    /**
     * 线程数
     */
    private static final int MAX_THREAD = 3;
    /**
     * 任务数量
     */
    private static final int TASK_COUNT = 3;
    /**
     * 目标总数
     */
    private static final int TARGET_COUNT = 1000000;

    private AtomicInteger acount = new AtomicInteger(0);

    private int count = 0;

    /**
     * 有所的加法
     *
     * @return
     */
    protected synchronized int inc() {
        return ++count;
    }

    protected synchronized int getCount() {
        return count;
    }

    class SyncTask implements Runnable {
        String name;
        long startTime;
        AtomicAndLock atomicAndLock;


        public SyncTask(long startTime, AtomicAndLock atomicAndLock) {
            this.startTime = startTime;
            this.atomicAndLock = atomicAndLock;
        }

        @Override
        public void run() {
            int inc = atomicAndLock.inc();
            while (inc < TARGET_COUNT) {
                inc = atomicAndLock.inc();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("SyncTask spend : " + (endTime - startTime) + " ms, " + "value = " + inc);
        }
    }


    class AtomicTask implements Runnable {
        String name;
        long startTime;

        public AtomicTask(long startTime) {
            this.startTime = startTime;
        }

        @Override
        public void run() {
            int inc = acount.incrementAndGet();
            while (inc < TARGET_COUNT) {
                inc = acount.incrementAndGet();
            }
            long endTime = System.currentTimeMillis();
            System.out.println("AtomicTask spend : " + (endTime - startTime) + " ms" + "value = " + inc);
        }
    }

}
